package xcmg.device.service.order;

import com.alibaba.nacos.common.utils.StringUtils;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.order.GpsMmJisoPoHeadDO;
import xcmg.device.dao.entity.order.GpsMmJisoPoLineVoteDO;
import xcmg.device.dao.entity.warehouse.WarehouseDO;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.order.GpsMmJisoPoHeadMapper;
import xcmg.device.dao.mapper.order.GpsMmJisoPoLineVoteMapper;
import xcmg.device.infra.BeanUtil;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.vo.order.GpsMmJisoPoHeadVO;
import xcmg.device.service.vo.order.GpsMmJisoPoLineVoteVO;
import xcmg.device.service.warehouse.WarehouseService;
import xcmg.syn.feign.SynClient;
import xcmg.syn.service.vo.order.MmJisoPoHeadVO;
import xcmg.syn.service.vo.order.MmJisoPoLineVoteVO;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.PageHelperPlus;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * GpsMmJisoPoHead 后台接口实现类
 */
@Slf4j
@Service
public class GpsMmJisoPoHeadService {

    @Autowired
    private SynClient synClient;
    @Autowired
    private GpsMmJisoPoHeadMapper gpsMmJisoPoHeadMapper;
    @Autowired
    private GpsMmJisoPoLineVoteMapper gpsMmJisoPoLineVoteMapper;

    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private GpsMmSwOrderService gpsMmSwOrderService;
    @Autowired
    private CompanyInfoMapper companyInfoMapper;
    @Autowired
    private MaterialsService materialsService;
    @Autowired
    private WarehouseService warehouseService;

    private static final int BATCH_SIZE = 5000;

    public PageCommonVO<GpsMmJisoPoHeadVO> list(SearchCommonVO<GpsMmJisoPoHeadVO> condition) {
        PageCommonVO<GpsMmJisoPoHeadVO> result = new PageCommonVO<>();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        PageHelperPlus.orderBy("t.PO_HEAD_ID desc");
        List<GpsMmJisoPoHeadVO> resultList = gpsMmJisoPoHeadMapper.queryList(condition.getFilters());
        result.setPageInfo(new PageInfo(resultList));
        List<GpsMmJisoPoHeadVO> voList = BeanUtil.do2bo4List(resultList, GpsMmJisoPoHeadVO.class);
        result.setPageInfoList(voList);
        return result;
    }

    public GpsMmJisoPoHeadVO getVoById(Long id,String orgId) {
        GpsMmJisoPoHeadVO v= getVoById(id);
        if (null != v &&StringUtils.isNoneBlank(v.getFactoryid()) && StringUtils.isNoneBlank(orgId)) {
            WarehouseDO wd= warehouseService.queryByFactoryId(v.getFactoryid(),orgId);
            if (null != wd) {
                v.setOutWarehouse(wd.getWarehouseCode());
             }
        }
        return v;
    }

    public GpsMmJisoPoHeadVO getVoById(Long id) {
        GpsMmJisoPoHeadVO vo = new GpsMmJisoPoHeadVO();
        vo.setPoHeadId(id);
        List<GpsMmJisoPoHeadVO> resultList = gpsMmJisoPoHeadMapper.queryList(vo);
        if (null != resultList && resultList.size() > 0) {
            processDetail(resultList);
            return resultList.get(0);
        }
        return null;
    }

    private void processDetail(List<GpsMmJisoPoHeadVO> resultList) {
        if (null == resultList || resultList.size() <= 0) {
            return;
        }
        List<Long> ids = resultList.stream().map(GpsMmJisoPoHeadVO::getPoHeadId).collect(Collectors.toList());
        GpsMmJisoPoLineVoteVO p = new GpsMmJisoPoLineVoteVO();
        p.setPoHeadIds(ids);
        List<GpsMmJisoPoLineVoteVO> list = gpsMmJisoPoLineVoteMapper.queryList(p);
        if (null != list && list.size() > 0) {
            Map<Long, List<GpsMmJisoPoLineVoteVO>> map = list.stream().collect(Collectors.groupingBy(GpsMmJisoPoLineVoteVO::getPoHeadId));
            for (GpsMmJisoPoHeadVO h : resultList) {
                h.setDetailList(map.get(h.getPoHeadId()));
            }
        }
    }


    public void syncGpsMmJisoPoHeadHandler(Date t, String querySupplierNo, boolean allSupplier) {
        log.info("syncGpsMmJisoPoHeadHandler ,t:{},querySupplierNo:{}", t, querySupplierNo);
        Map<String, CompanyInfoDO> companyCache = new HashMap<>();
        if (null == querySupplierNo && allSupplier) {
            companyCache.putAll(companyInfoService.queryCommpanyInfo(null));
        }
        CompanyInfoDO factoryCompanyInfo = companyInfoMapper.itemByOrgCode("GAC");
        if (factoryCompanyInfo == null) {
            log.error("没有找到GAC的核心企业");
            return;
        }

        MmJisoPoHeadVO voParam = new MmJisoPoHeadVO();
        Long maxOrderId = null;
        while (true) {
            //如果有时间，根据时间增量同步
            voParam.setLastModifiedTimeStart(t);
            voParam.setLimitNum(BATCH_SIZE);
            voParam.setSupplierno(querySupplierNo);
            voParam.setMinOrderId(maxOrderId);
            ActionResult<List<MmJisoPoHeadVO>> listActionResult = synClient.listMmJisoPoHead(voParam);
            if (null == listActionResult || CollectionUtils.isEmpty(listActionResult.getValue())) {
                log.error("同步GPS数据失败,voParam：{},\n listActionResult:{}", voParam, listActionResult);
                break;
            }
            List<MmJisoPoHeadVO> orders = listActionResult.getValue();
            boolean fullPage = (orders.size() == BATCH_SIZE);
            maxOrderId = orders.get(orders.size() - 1).getPoHeadId();
            if (companyCache.isEmpty() || !allSupplier) {
                //没有明细行
                Set<String> suplierNos = orders.stream().filter(o -> CollectionUtils.isNotEmpty(o.getDetailList()))
                        .map(MmJisoPoHeadVO::getSupplierno).collect(Collectors.toSet());
                if (suplierNos.isEmpty()) {
                    log.error("剔除无明细行后，供应商空，本次不执行。voParam: {}", voParam);
                    continue;
                }
                gpsMmSwOrderService.query2CompanyCache(companyCache, suplierNos);
            }
            if (companyCache.isEmpty()) {
                log.error("没有找到对应的供应商");
                continue;
            }
            List<MmJisoPoHeadVO> okList = new ArrayList<>(orders.size());
            Set<String> materialsNos = new HashSet<>();
            for (MmJisoPoHeadVO mvo : orders) {
                CompanyInfoDO companyInfoDO = companyCache.get(mvo.getSupplierno());
                if (null == companyInfoDO) {
                    log.error("没有找到对应的供应商,{}", mvo);
                    continue;
                }
                if (CollectionUtils.isEmpty(mvo.getDetailList())) {
                    log.error("没有明细,{}", mvo);
                    continue;
                }
                materialsNos.addAll(mvo.getDetailList().stream().map(MmJisoPoLineVoteVO::getItem).collect(Collectors.toSet()));
                mvo.setOrgId(companyInfoDO.getOrgId());
                mvo.setSupplierName(companyInfoDO.getCompanyName());
                okList.add(mvo);
            }
            Map<String, PriMaterialsDO> mmap = materialsService.queryPriMaterialsByMaterialsNos(new ArrayList<>(materialsNos), factoryCompanyInfo.getOrgId());
            if (CollectionUtils.isNotEmpty(okList)) {
                Date now = new Date();
                Lists.partition(okList, 50).forEach(subOrders -> {
                    List<GpsMmJisoPoHeadDO> hl = new ArrayList<>();
                    List<GpsMmJisoPoLineVoteDO> bl = new ArrayList<>();
                    subOrders.forEach(o -> {
                        if (CollectionUtils.isNotEmpty(o.getDetailList())) {
                            for (MmJisoPoLineVoteVO detailVO : o.getDetailList()) {
                                GpsMmJisoPoLineVoteDO d = BeanUtil.do2bo(detailVO, GpsMmJisoPoLineVoteDO.class);
                                PriMaterialsDO priMaterialsDO = mmap.get(detailVO.getItem());
                                if (priMaterialsDO != null) {
                                    d.setMaterialsShortNo(priMaterialsDO.getMaterialsShortNo());
                                    d.setMaterialsDes(priMaterialsDO.getMaterialsDes());
                                }
                                d.setUpdateTime(now);
                                bl.add(d);
                            }
                            GpsMmJisoPoHeadDO m = BeanUtil.do2bo(o, GpsMmJisoPoHeadDO.class);
                            m.setUpdateTime(now);
                            hl.add(m);
                        }
                    });
                    try {
                        if (CollectionUtils.isNotEmpty(hl)) {
                            gpsMmJisoPoLineVoteMapper.batchSave(bl);
                            gpsMmJisoPoHeadMapper.batchSave(hl);
                        }
                    } catch (Exception e) {
                        log.error("同步GPS数据失败,voParam：{}", voParam, e);
                        throw new RuntimeException(e);
                    }
                });
            }
            if (!fullPage) {
                log.info("当前查询不满页,同步GPS数据完成,size:{}", orders.size());
                break;
            } else {
                log.info("当前查询满页,maxOrderId:{}", maxOrderId);
            }
        }
    }

    public void updateById(GpsMmJisoPoHeadDO sod) {
        gpsMmJisoPoHeadMapper.updateNotNullByPrimaryKeySelective(sod);
    }
}
